# converters/appimage.py
import subprocess
import re
import os

class AppImageConverter:
    def __init__(self, log_callback, dependency_map):
        self.log = log_callback
        self.dependency_map = dependency_map

    def convert(self, wsl_file_path, temp_dir):
        """转换 AppImage 包"""
        self.log("开始转换 AppImage 包...\n")

        # Step 1: 提取 AppImage 内容
        extract_dir = f"{temp_dir}/appimage-extract"
        cmd_extract = f'wsl mkdir -p {extract_dir} && wsl chmod +x "{wsl_file_path}" && wsl "{wsl_file_path}" --appimage-extract --destination {extract_dir}'
        self._run_wsl_command(cmd_extract)

        # Step 2: 分析依赖
        cmd_find_bin = f'wsl find {extract_dir} -type f -executable -print -quit'
        bin_path = subprocess.check_output(cmd_find_bin, shell=True, text=True).strip()
        
        cmd_ldd = f'wsl ldd "{bin_path}"'
        ldd_output = subprocess.check_output(cmd_ldd, shell=True, text=True)
        libs = re.findall(r'=>\s+(/.+?)\s+', ldd_output)

        # Step 3: 生成 linglong.yaml
        yaml_content = f"""package:
  id: com.appimage.converted.{os.path.basename(bin_path)}
  version: 1.0.0
  runtime: org.deepin.Runtime/20/x86_64
  base: minimal

files:
  - from: {extract_dir}/
    to: /

dependencies:
  - runtime: org.deepin.Runtime/20/x86_64
"""

        # 添加依赖映射
        for lib in libs:
            lib_name = os.path.basename(lib).split('.')[0]
            if lib_name in self.dependency_map:
                yaml_content += f"  - {lib_name}: {self.dependency_map[lib_name]}\n"

        # 保存 yaml 文件
        cmd_gen_yaml = f'wsl bash -c "echo \'{yaml_content}\' > {temp_dir}/linglong/linglong.yaml"'
        self._run_wsl_command(cmd_gen_yaml)

        # Step 4: 构建玲珑包
        cmd_build = f'wsl mkdir -p {temp_dir}/linglong && cd {temp_dir}/linglong && ll-builder build'
        self._run_wsl_command(cmd_build)

    def _run_wsl_command(self, cmd):
        """执行 WSL 命令并实时输出日志"""
        process = subprocess.Popen(
            cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
        )
        for line in process.stdout:
            self.log(line)
        process.wait()
        if process.returncode != 0:
            raise subprocess.CalledProcessError(process.returncode, cmd)